package it.controllocredito.backend;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DataConversionUtil {
	private static final long YEAR_IN_MILLIS=31558464000l;
	
	/**
	 * Restituisce la differenza tra due date (<code>date1-date2</code>) come un intero rappresentante la differenza in giorni, mesi, anni 
	 * in base alla valorizzazione del parametro <code>returnDiff</code>.
	 * 
	 * Il metodo calcola anche la differenza in settimane ma non e' impostato per restituirla.
	 * 
	 * @param date1 La data sottraenda.
	 * @param date2 La data sottratta.
	 * @param returnDiff Imposta la differenza di ritorno. Il parametro accetta i valori costanti esposti dalla classe {@link Calendar}:<br>
	 * 						<ul>
	 * 							<li> {@link Calendar#DATE} -> imposta la differenza di ritorno in <b>GIORNI</b>;
	 *						    <li> {@link Calendar#MONTH} -> imposta la differenza di ritorno in <b>MESI</b>;
	 *						    <li> {@link Calendar#YEAR} -> imposta la differenza di ritorno in <b>ANNI</b>;
	 * 						</ul>
	 * 					Per ogni valore diverso dai sopraindicati il metodo restituisce la differenza in <b>GIORNI</b>.
	 * @return La differenza in <b>GIORNI</b> o <b>MESI</b> o <b>ANNI</b> tra le due date.
	 */
	public static int differenzaDate(Date date1, Date date2, int returnDiff){

		Calendar cal1 = Calendar.getInstance(); ; 
		Calendar cal2 = Calendar.getInstance(); ;
		
		// different date might have different offset
		cal1.setTime(date1);          
		long ldate1 = date1.getTime();
		cal2.setTime(date2);
		long ldate2 = date2.getTime();
		
		// Use integer calculation, truncate the decimals
		int hr1   = (int)(ldate1/3600000); //60*60*1000
		int hr2   = (int)(ldate2/3600000);
		int days1 = hr1/24;
		int days2 = hr2/24;
		int dateDiff  = days2 - days1;
//		int weekOffset = (cal2.get(Calendar.DAY_OF_WEEK) - cal1.get(Calendar.DAY_OF_WEEK))<0 ? 1 : 0;
//		int weekDiff  = dateDiff/7 + weekOffset; 
		int yearDiff  = cal2.get(Calendar.YEAR) - cal1.get(Calendar.YEAR); 
		int monthDiff = yearDiff * 12 + cal2.get(Calendar.MONTH) - cal1.get(Calendar.MONTH);
		
		int returnValue;
		
		switch(returnDiff){
			case Calendar.DATE: returnValue=dateDiff; break;
			case Calendar.MONTH: returnValue=monthDiff; break;
			case Calendar.YEAR: returnValue=yearDiff; break;
			default: returnValue=dateDiff; break;
		}
		
		return returnValue;
	}
	
	public static int getAnno(Date date) {

		Calendar cal = Calendar.getInstance(); ; 
		
		cal.setTime(date);          
		
		return cal.get(Calendar.YEAR); 
	
	}
	
	public static int getMese(Date date) {

		Calendar cal = Calendar.getInstance(); ; 
		
		cal.setTime(date);          
		
		return cal.get(Calendar.MONTH); 
	
	}
	
	public static int getGiorno(Date date) {

		Calendar cal = Calendar.getInstance(); ; 
		
		cal.setTime(date);          
		
		return cal.get(Calendar.DAY_OF_MONTH); 
	
	}
	/**
	 * Verifica che la data passata sia precedente a <code>years</code> anni fa. Il metodo effettua la verifica su anni/mesi/giorni in base al parametro
	 * <code>comparisonField</code> passato.
	 * <p>
	 * <b>Es.:</b><br>
	 * <code>beforeNYearsAgo([15/10/1998], 3, {@link Calendar#MONTH})</code><br>
	 * verifichera' che la data passata <i>15/10/1998</i> sia piu vecchia di <i>3</i> anni rispetto ad oggi. La verifica verra' effettuata sul numero di mesi.
	 * </p>
	 * 
	 * @param date La data da validare
	 * @param years Il numero di anni su cui fare il check
	 * @param comparisonField Imposta il campo di comparazione. Il parametro accetta i valori costanti esposti dalla classe {@link Calendar}:<br>
	 * 						<ul>
	 * 							<li> {@link Calendar#DATE} -> imposta la differenza di ritorno in <b>GIORNI</b>;
	 *						    <li> {@link Calendar#MONTH} -> imposta la differenza di ritorno in <b>MESI</b>;
	 *						    <li> {@link Calendar#YEAR} -> imposta la differenza di ritorno in <b>ANNI</b>;
	 * 						</ul>
	 * 					Per ogni valore diverso dai sopraindicati il metodo restituisce la differenza in <b>GIORNI</b>.
//	 * @return <code>true</code> se la data passata come parametro e' minore di <code>years</code> anni fa.
	 */
	public static boolean beforeNYearsAgo(Date date, int years, int comparisonField){
		
		int comparisonValue;
		
		switch(comparisonField){
			case Calendar.DATE: comparisonValue=365*years; break;
			case Calendar.MONTH: comparisonValue=12*years; break;
			case Calendar.YEAR: comparisonValue=years; break;
			default: comparisonValue=365*years; break;
		}
		
		int differenzaDate=differenzaDate(date, Calendar.getInstance().getTime(),comparisonField);
		
		return !(differenzaDate<comparisonValue);
	}
	
	public static int calcolaEta(Date dataNascita){
		try {
			long etaMillis=System.currentTimeMillis()-dataNascita.getTime();
			return (int)(etaMillis/YEAR_IN_MILLIS);
		}catch (NullPointerException e) {
			e.printStackTrace();
			return 0;
		}
	}
	
	public static void main(String args[]){
		SimpleDateFormat sdf= new SimpleDateFormat("dd/MM/yyyy");
		String dataNascitaString="26/04/1980 ";
//		String anniPatente="18";
//		
		Calendar dataNascita=Calendar.getInstance();
//		Calendar dataMinimaPatente=Calendar.getInstance();
//		
		try {
			dataNascita.setTime(sdf.parse(dataNascitaString));
//			dataMinimaPatente.setTime(sdf.parse(dataNascitaString));
		} catch (ParseException e) {
			e.printStackTrace();
		}
//		
//		dataMinimaPatente.add(Calendar.YEAR, Integer.parseInt(anniPatente));
		
//		System.out.println("Data conseguimento patente: "+sdf.format(dataMinimaPatente.getTime()));
//		System.out.println("Data conseguimento patente e' precedente a 3 anni fa? "+beforeNYearsAgo(dataMinimaPatente.getTime(), 3, Calendar.MONTH));
		
		System.out.println(calcolaEta(dataNascita.getTime()));
	}
	
}
